//
// Created by 33145 on 2023/4/3.
//

#include "chat_server.h"

static sylar::Logger::ptr g_logger = SYLAR_LOG_NAME("system");

chat::ChatServer::ChatServer(sylar::IOManager *worker, sylar::IOManager *io_worker,
                                    sylar::IOManager *accept_worker) : TcpServer(worker, io_worker, accept_worker) {
  m_type = "websocket_server";
  m_servlet.reset(new ChatWSServlet);
}

void chat::ChatServer::handleClient(sylar::Socket::ptr client) {
  SYLAR_LOG_DEBUG(g_logger) << "handleClient\n" << *client;
  sylar::http::WSSession::ptr session(new sylar::http::WSSession(client));
  do {
    /// 处理时会先检查协议是否被升级为WebSocket，检查完会回复一个rsp
    /// WebSocket的特点，两端只需要交换一次HTTP请求就可以一直发送消息
    /// 也对应了交互性强的需求（消息比较短，使用很长的HTTP头进行消息传递，得不偿失）
    sylar::http::HttpRequest::ptr header = session->handleShake();
    if(!header) {
      SYLAR_LOG_DEBUG(g_logger) << "handleShake error";
      break;
    }
    /// 用来处理刚建立连接时的自定义回调
    int rt = m_servlet->onConnect(header, session);
    if(rt) {
      SYLAR_LOG_DEBUG(g_logger) << "onConnect return " << rt;
      break;
    }
    while(true) {
      /// 如果两分钟客户端未收到消息，则会向服务器发送断开连接的请求
      auto msg = session->recvMessage();
      // SYLAR_LOG_DEBUG(g_logger) << "recv some message: " << msg->getData();
      if(!msg) {
        break;
      }
      /// 处理业务
      rt = m_servlet->handle(header, msg, session);
      if(rt) {
        SYLAR_LOG_DEBUG(g_logger) << "handle return " << rt;
        break;
      }
    }
    /// 用来处理连接断开时的自定义回调
    m_servlet->onClose(header, session);
  } while(false);
  // SYLAR_LOG_DEBUG(g_logger) << "close";
  session->close();
}
